#include <string.h>
#include <iostream>

using std::cout;
using std::endl;

class Base
{
public:
    Base(const char *pbase)
    : _pbase(new char[strlen(pbase) + 1]())
    {
        cout <<"Base(const char *)" << endl;
        strcpy(_pbase, pbase);
    }

    virtual
    void print() const
    {
        cout << "Base::_pbase = " << _pbase << endl;
    }

    //如果将基类的析构函数设置为虚函数，那么派生类的析构函数
    //会自动变为虚函数，认为其是一种重写(C++唯一的名字不一样
    //的重写)
    //原因：对于任何一个类而言，析构函数是唯一的，不能重载
    //对于编译器而言，只要类定义了析构函数，将其改名为
    //~destructor(),对于编译器而言，这就是一个重写
    virtual
    ~Base()
    {
        cout << "~Base()" << endl;
        if(_pbase)
        {
            delete [] _pbase;
            _pbase = nullptr;
        }
    }

private:
    char *_pbase;
};

class Derived
: public Base
{
public:
    Derived(const char *pbase, const char *pderived)
    : Base(pbase)
    , _pderived(new char[strlen(pderived) + 1]())
    {
        cout << "Derived(const char *, const char *)" << endl;
        strcpy(_pderived, pderived);
    }

    void print() const
    {
        cout << "Derived::_pderived = " << _pderived << endl;
    }

    ~Derived()
    {
        cout << "~Derived()" << endl;
        if(_pderived)
        {
            delete [] _pderived;
            _pderived = nullptr;
        }
    }
private:
    char *_pderived;
};

void test()
{
    //内存泄漏：派生类中的数据成员申请的空间没有回收
    Base *pbase = new Derived("hello", "world");
    pbase->print();

    /* delete dynamic_cast<Derived *>(pbase);//ok */
    //delete pbase会执行delete表达式的工作步骤
    //1、执行该种类型的析构函数pbase->~Base()
    //2、执行operator delete
    delete pbase;
    pbase = nullptr;
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

